package cyningxu.findviewbyx.action;

import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import cyningxu.findviewbyx.model.ViewPart;
import cyningxu.findviewbyx.util.ActionUtil;
import cyningxu.findviewbyx.util.ViewSaxHandler;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

public class FindViewDialog extends JDialog {
    private boolean isViewHolder;
    private final ViewSaxHandler viewSaxHandler;
    private JPanel contentPane;
    public JButton btnCopyCode;
    public JButton btnClose;
    public JTextField textRootView;
    public JTextArea textCode;
    public JCheckBox chbAddM;
    public JTable tableViews;
    public JButton btnSelectAll;
    public JButton btnSelectNone;
    public JButton btnNegativeSelect;
    private JCheckBox chbIsViewHolder;
    private JButton AddRootView;
    private JComboBox comboBox;
    private ArrayList<PsiFile> psiFiles;
    private List<ViewPart> viewParts;
    private DefaultTableModel tableModel;

    public FindViewDialog(final Project project, String layoutPath, ArrayList<PsiFile> list) {
        isViewHolder = false;
        viewSaxHandler = new ViewSaxHandler();
        viewSaxHandler.setLayoutPath(layoutPath);
        viewSaxHandler.setProject(project);
        tableViews.setRowHeight(30);
        this.psiFiles = list;
        for (PsiFile file : list) {
            comboBox.addItem(file.getName());
        }
        if (list.size() == 1) {
            comboBox.setEnabled(false);
        }
        comboBox.setSelectedIndex(0);
        getViewList(psiFiles.get(comboBox.getSelectedIndex()));
        comboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                viewSaxHandler.clearViewPartList();
                getViewList(psiFiles.get(comboBox.getSelectedIndex()));
                ActionUtil.switchAddM(viewParts, chbAddM.isSelected());
                updateTable();
            }
        });
        setContentPane(contentPane);
        setModal(true);

        btnCopyCode.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
                Transferable tText = new StringSelection(textCode.getText());
                clip.setContents(tText, null);
                onCancel();
            }
        });

        ActionUtil.switchAddM(viewParts, chbAddM.isSelected());
        chbAddM.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                ActionUtil.switchAddM(viewParts, chbAddM.isSelected());
                updateTable();
            }
        });

        chbIsViewHolder.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                isViewHolder = chbIsViewHolder.isSelected();
                generateCode();
                if (chbIsViewHolder.isSelected()) {
                    AddRootView.setEnabled(false);
                    textRootView.setEnabled(false);
                } else {
                    AddRootView.setEnabled(true);
                    textRootView.setEnabled(true);
                }
            }
        });

        AddRootView.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                generateCode();
            }
        });

        btnClose.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                FindViewDialog.this.onCancel();
            }
        });
        btnSelectAll.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (ViewPart viewPart : viewParts) {
                    viewPart.setSelected(true);
                }
                updateTable();
            }
        });

        btnSelectNone.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (ViewPart viewPart : viewParts) {
                    viewPart.setSelected(false);
                }
                updateTable();
            }
        });

        btnNegativeSelect.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (ViewPart viewPart : viewParts) {
                    viewPart.setSelected(!viewPart.isSelected());
                }
                updateTable();
            }
        });
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

        contentPane.registerKeyboardAction(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        FindViewDialog.this.onCancel();
                    }
                },
                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        updateTable();
    }

    private void updateTable() {
        if (viewParts == null || viewParts.size() == 0) {
            return;
        }
        tableModel = ActionUtil.getTableModel(viewParts, tableModelListener);
        setModel(tableModel);
        generateCode();
    }

    TableModelListener tableModelListener = new TableModelListener() {
        @Override
        public void tableChanged(TableModelEvent event) {
            if (tableModel == null) {
                return;
            }
            int row = event.getFirstRow();
            int column = event.getColumn();
            if (column == 0) {
                Boolean isSelected = (Boolean) tableModel.getValueAt(row, column);
                viewSaxHandler.getViewPartList().get(row).setSelected(isSelected);
                generateCode();
            }
        }
    };

    private void generateCode() {
        setTextCode(ActionUtil.generateCode(viewParts, isViewHolder, getRootView()));
    }

    private void onCancel() {
        dispose();
    }

    public void setTextCode(String codeStr) {
        textCode.setText(codeStr);
    }

    public void setModel(DefaultTableModel model) {
        tableViews.setModel(model);
        tableViews.getColumnModel().getColumn(0).setPreferredWidth(20);
    }

    public String getRootView() {
        return textRootView.getText().trim();
    }

    private void getViewList(PsiFile psiFile) {
        String contentStr = psiFile.getText();
        viewParts = ActionUtil.getViewPartList(viewSaxHandler, contentStr);
    }
}
